import { CSSValue, TComponent } from '@material/typeing';
import { useState, useEffect, useRef, useCallback, FC, CSSProperties } from 'react';
import $style from './index.scss';
export interface TypewriterProps extends TComponent {
    /** 要显示的文本 */
    text: string | string[];
    /** 打字速度（毫秒/字符），默认100ms */
    typingSpeed?: number;
    /** 超时时间（毫秒），默认5000ms */
    timeout?: number;
    /** 是否在所有文字打完后立即结束 */
    terminateOnComplete?: boolean;
    /** 自定义类名 */
    className?: string;
    /** 打字结束后的回调函数 */
    onComplete?: () => void;
    /** 光标的样式 **/
    cursorClassName?: CSSValue;
    cursorStyle?: CSSProperties;
}

// 使用React.memo避免不必要的重渲染
const Typewriter: FC<TypewriterProps> = function ({
    text,
    typingSpeed = 60,
    timeout = 5000,
    terminateOnComplete = true,
    className,
    cursorClassName,
    cursorStyle,
    onComplete
}) {
    // 状态管理 - 仅保留必要的状态
    const [displayedText, setDisplayedText] = useState('');
    const [isComplete, setIsComplete] = useState(false);

    // 使用ref存储不需要触发重渲染的变量
    const lastUpdateTimeRef = useRef<number>(Date.now());
    const currentIndexRef = useRef<number>(0);
    const requestRef = useRef<number>(0);
    const fullTextRef = useRef<string>(Array.isArray(text) ? text.join('') : text);
    const isAnimatingRef = useRef<boolean>(false);
    const typeNextCharacterRef = useRef<() => void>(() => {});
    // 存储当前的terminateOnComplete值
    const terminateOnCompleteRef = useRef(terminateOnComplete);
    const onCompleteRef = useRef(onComplete); // 存储回调引用
    // 打字核心逻辑 - 使用useCallback确保引用稳定
    // 更新回调引用，避免闭包问题
    useEffect(() => {
        onCompleteRef.current = onComplete;
    }, [onComplete]);
    const typeNextCharacter = useCallback(() => {
        const now = Date.now();
        const fullText = fullTextRef.current;
        const currentTerminateOnComplete = terminateOnCompleteRef.current;

        // 如果已经完成则停止动画
        if (isComplete) {
            isAnimatingRef.current = false;
            return;
        }

        // 还有字符需要打印
        if (currentIndexRef.current < fullText.length) {
            // 检查是否到了打字时机
            if (now - lastUpdateTimeRef.current >= typingSpeed) {
                const nextChar = fullText[currentIndexRef.current];
                // 确保字符存在，避免undefined
                if (nextChar) {
                    setDisplayedText((prev) => prev + nextChar);
                }
                currentIndexRef.current = currentIndexRef.current + 1;
                lastUpdateTimeRef.current = now;
            }
            // 继续请求下一帧
            requestRef.current = requestAnimationFrame(typeNextCharacterRef.current);
        } else {
            // 所有字符都已打印完成
            if (currentTerminateOnComplete) {
                // 立即标记为完成
                setIsComplete(true);
                onCompleteRef.current?.();
                isAnimatingRef.current = false;
            } else {
                // 检查超时
                if (now - lastUpdateTimeRef.current >= timeout) {
                    setIsComplete(true);
                    onCompleteRef.current?.();
                    isAnimatingRef.current = false;
                } else {
                    // 继续检查超时
                    requestRef.current = requestAnimationFrame(typeNextCharacterRef.current);
                }
            }
        }
    }, [isComplete, typingSpeed, timeout]);

    // 存储typeNextCharacter引用，避免循环依赖
    useEffect(() => {
        typeNextCharacterRef.current = typeNextCharacter;
    }, [typeNextCharacter]);

    // 处理文本更新
    useEffect(() => {
        const newFullText = Array.isArray(text) ? text.join('') : text;
        if (newFullText !== fullTextRef.current) {
            fullTextRef.current = newFullText;
            // 当terminateOnComplete为false时，接着之前的继续打印
            if (!terminateOnCompleteRef.current) {
                setIsComplete(false);
                // 如果已经完成或动画已停止，重新启动
                if (!isAnimatingRef.current) {
                    isAnimatingRef.current = true;
                    requestRef.current = requestAnimationFrame(typeNextCharacterRef.current);
                }
            }
        }
    }, [text]);

    // 处理terminateOnComplete更新（包括初始化）
    useEffect(() => {
        terminateOnCompleteRef.current = terminateOnComplete;

        if (!fullTextRef.current && terminateOnCompleteRef.current) {
            setDisplayedText('');
            setIsComplete(true);
            if (requestRef.current) {
                cancelAnimationFrame(requestRef.current);
            }
            isAnimatingRef.current = false;
            onCompleteRef.current?.();
            currentIndexRef.current = 0;
            return;
        }
        // 如果正在动画中，不需要重新开始，只需更新引用即可
        if (isAnimatingRef.current) {
            return;
        }
        // 如果动画已停止但未完成，根据新的属性决定是否继续
        if (!isComplete) {
            isAnimatingRef.current = true;
            requestRef.current = requestAnimationFrame(typeNextCharacterRef.current);
        }
    }, [terminateOnComplete, isComplete]);

    // 初始化打字效果 - 不再直接使用terminateOnComplete
    useEffect(() => {
        // 重置状态
        setDisplayedText('');
        currentIndexRef.current = 0;
        setIsComplete(false);
        lastUpdateTimeRef.current = Date.now();
        isAnimatingRef.current = true;

        // 开始动画
        requestRef.current = requestAnimationFrame(typeNextCharacterRef.current);

        // 清理函数 - 组件卸载时停止动画
        return () => {
            if (requestRef.current) {
                cancelAnimationFrame(requestRef.current);
            }
            isAnimatingRef.current = false;
        };
    }, [typingSpeed, timeout]); // 不再包含terminateOnComplete

    return (
        <div className={[$style.typewriter, className]}>
            {displayedText}
            {!isComplete && (
                <span
                    style={cursorStyle}
                    className={[$style.cursor, cursorClassName]}
                >
                    |
                </span>
            )}
        </div>
    );
};

export default Typewriter;
